package com.admin_system.service.impl;

import com.admin_system.entity.MergeResponse;
import com.admin_system.service.DocumentMergeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DocumentMergeServiceImpl implements DocumentMergeService {

    @Value("${python.document-merger-service.url}")
    private String pythonServiceUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public MergeResponse mergeDocuments(List<MultipartFile> paperFiles, List<MultipartFile> answerFiles,
                                        String outputFormat, String mergeOrder) {
        log.info("开始合并文档请求，输出格式: {}, 合并顺序: {}", outputFormat, mergeOrder);
        
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        
        // 添加试卷文件
        if (paperFiles != null && !paperFiles.isEmpty()) {
            paperFiles.forEach(file -> {
                try {
                    body.add("paper_files", new MultipartFileResource(file));
                } catch (Exception e) {
                    log.error("添加试卷文件失败", e);
                }
            });
        }
        
        // 添加答案文件
        if (answerFiles != null && !answerFiles.isEmpty()) {
            answerFiles.forEach(file -> {
                try {
                    body.add("answer_files", new MultipartFileResource(file));
                } catch (Exception e) {
                    log.error("添加答案文件失败", e);
                }
            });
        }
        
        // 添加参数
        body.add("output_format", outputFormat);
        body.add("merge_order", mergeOrder);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        
        try {
            // 修改为使用Map接收响应，以便适应Python服务返回的格式
            ResponseEntity<Map> response = restTemplate.exchange(
                    pythonServiceUrl + "/api/merge",
                    HttpMethod.POST,
                    requestEntity,
                    Map.class
            );
            
            Map<String, Object> responseMap = response.getBody();
            log.info("收到Python服务响应: {}", responseMap);
            
            // 从响应Map中构建MergeResponse对象
            MergeResponse mergeResponse = new MergeResponse();
            
            if (responseMap != null) {
                if (responseMap.containsKey("task_id")) {
                    mergeResponse.setTaskId((String) responseMap.get("task_id"));
                }
                if (responseMap.containsKey("status")) {
                    mergeResponse.setStatus((String) responseMap.get("status"));
                }
                if (responseMap.containsKey("message")) {
                    mergeResponse.setMessage((String) responseMap.get("message"));
                }
                
                // 设置合并后的文件名
                if (paperFiles != null && !paperFiles.isEmpty()) {
                    String firstFileName = paperFiles.get(0).getOriginalFilename();
                    if (firstFileName != null) {
                        int lastDotIdx = firstFileName.lastIndexOf('.');
                        String baseName = lastDotIdx > 0 ? firstFileName.substring(0, lastDotIdx) : firstFileName;
                        String extension = lastDotIdx > 0 ? firstFileName.substring(lastDotIdx) : "";
                        mergeResponse.setOriginalFilename(baseName + "_合并" + extension);
                        log.info("设置合并文件名: {}", mergeResponse.getOriginalFilename());
                    }
                }
            }
            
            log.info("文档合并请求已发送，任务ID: {}", mergeResponse.getTaskId());
            return mergeResponse;
        } catch (Exception e) {
            log.error("调用Python服务合并文档失败", e);
            MergeResponse errorResponse = new MergeResponse();
            errorResponse.setStatus("failed");
            errorResponse.setMessage("调用合并服务失败: " + e.getMessage());
            return errorResponse;
        }
    }

    @Override
    public MergeResponse getTaskStatus(String taskId) {
        log.info("获取任务状态, 任务ID: {}", taskId);
        
        int maxRetries = 3;
        int retryCount = 0;
        long retryDelay = 500; // 初始重试延迟500毫秒
        
        while (retryCount < maxRetries) {
            try {
                // 修改为使用Map接收响应
                ResponseEntity<Map> response = restTemplate.getForEntity(
                        pythonServiceUrl + "/api/task/" + taskId,
                        Map.class
                );
                
                Map<String, Object> responseMap = response.getBody();
                log.info("获取任务状态响应: {}", responseMap);
                
                // 从响应Map中构建MergeResponse对象
                MergeResponse mergeResponse = new MergeResponse();
                
                if (responseMap != null) {
                    mergeResponse.setTaskId(taskId);
                    
                    if (responseMap.containsKey("status")) {
                        mergeResponse.setStatus((String) responseMap.get("status"));
                    }
                    if (responseMap.containsKey("message")) {
                        mergeResponse.setMessage((String) responseMap.get("message"));
                    }
                    if (responseMap.containsKey("progress")) {
                        Object progress = responseMap.get("progress");
                        if (progress instanceof Integer) {
                            mergeResponse.setProgress((Integer) progress);
                        } else if (progress instanceof Double) {
                            mergeResponse.setProgress(((Double) progress).intValue());
                        }
                    }
                    if (responseMap.containsKey("output_path")) {
                        mergeResponse.setOutputPath((String) responseMap.get("output_path"));
                    }
                    if (responseMap.containsKey("original_filename")) {
                        mergeResponse.setOriginalFilename((String) responseMap.get("original_filename"));
                        log.info("获取到原始文件名: {}", mergeResponse.getOriginalFilename());
                    }
                }
                
                return mergeResponse;
            } catch (Exception e) {
                // 检查是否是404错误
                if (e.getMessage() != null && e.getMessage().contains("404")) {
                    retryCount++;
                    if (retryCount < maxRetries) {
                        log.info("任务状态查询返回404，第{}次重试，等待{}毫秒", retryCount, retryDelay);
                        try {
                            Thread.sleep(retryDelay);
                            retryDelay *= 2; // 指数退避
                            continue;
                        } catch (InterruptedException ie) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                }
                
                log.error("获取任务状态失败, 任务ID: {}", taskId, e);
                MergeResponse errorResponse = new MergeResponse();
                errorResponse.setStatus("failed");
                errorResponse.setMessage("获取任务状态失败: " + e.getMessage());
                return errorResponse;
            }
        }
        
        // 所有重试都失败后返回错误响应
        MergeResponse errorResponse = new MergeResponse();
        errorResponse.setStatus("failed");
        errorResponse.setMessage("获取任务状态失败: 任务可能正在初始化，请稍后重试");
        return errorResponse;
    }

    @Override
    public Resource downloadMergedDocument(String taskId) {
        log.info("下载合并文档, 任务ID: {}", taskId);
        
        try {
            ResponseEntity<byte[]> response = restTemplate.getForEntity(
                    pythonServiceUrl + "/api/download/" + taskId,
                    byte[].class
            );
            
            ByteArrayResource resource = new ByteArrayResource(response.getBody());
            return resource;
        } catch (Exception e) {
            log.error("下载合并文档失败, 任务ID: {}", taskId, e);
            throw new RuntimeException("下载合并文档失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> checkPythonServiceStatus() {
        log.info("检查Python服务状态: {}", pythonServiceUrl);
        
        try {
            ResponseEntity<Map> response = restTemplate.getForEntity(
                    pythonServiceUrl + "/api/status",
                    Map.class
            );
            
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("Python服务返回非成功状态码: {}", response.getStatusCode());
                throw new RuntimeException("Python服务返回错误: " + response.getStatusCode());
            }
            
            Map<String, Object> statusMap = response.getBody();
            log.info("Python服务状态: {}", statusMap);
            return statusMap;
        } catch (Exception e) {
            log.error("无法连接到Python服务", e);
            throw new RuntimeException("无法连接到Python服务: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> cleanupTempFiles() {
        log.info("请求清理临时文件和过期任务");
        
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            HttpEntity<String> requestEntity = new HttpEntity<>("{}", headers);
            
            ResponseEntity<Map> response = restTemplate.exchange(
                    pythonServiceUrl + "/api/cleanup",
                    HttpMethod.POST,
                    requestEntity,
                    Map.class
            );
            
            if (!response.getStatusCode().is2xxSuccessful()) {
                log.error("Python服务清理操作返回非成功状态码: {}", response.getStatusCode());
                throw new RuntimeException("Python服务清理操作返回错误: " + response.getStatusCode());
            }
            
            Map<String, Object> resultMap = response.getBody();
            log.info("清理操作结果: {}", resultMap);
            return resultMap;
        } catch (Exception e) {
            log.error("请求清理操作失败", e);
            throw new RuntimeException("请求清理操作失败: " + e.getMessage());
        }
    }

    /**
     * 内部类，用于将MultipartFile转换为Resource发送给Python服务
     */
    private static class MultipartFileResource extends ByteArrayResource {
        private final String filename;

        public MultipartFileResource(MultipartFile file) throws Exception {
            super(file.getBytes());
            this.filename = file.getOriginalFilename();
        }

        @Override
        public String getFilename() {
            return this.filename;
        }
    }
} 